#pragma once 

#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>

#define ONCE_SIZE 128

//1:本轮读取全部完成
//-1:读取出错
//0:对端关闭链接
int recver_core(int sock, std::string& inbuffer)
{
    while(true)
    {
        char buffer[ONCE_SIZE];
        ssize_t ret = recv(sock, buffer, ONCE_SIZE - 1, 0);
        if (ret > 0)
        {
            buffer[ret] = '\0';
            //读取成功
            inbuffer += buffer;
        }
        else if (ret < 0)
        {
            //IO被信号打断,概率特别低
            if (errno == EINTR)
            {
                continue;
            }
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                //读完底层没有数据了,因为是非阻塞的原因,所以会到这里
                break;
            }
            return -1;
        }
        else
        {
            //s == 0, 对方关闭链接
            return 0;
        }
    }
    return 1;
}

// 1: 全部将数据发送完成
// 0: 数据没有发完，但是不能再发了
//-1: 发送失败
int sender_core(int sock, std::string& outbuffer)
{
    while (true)
    {
        //本轮累计发送的数据量
        int total = 0;
        const char* start = outbuffer.c_str();
        int size = outbuffer.size();
        ssize_t ret = send(sock, start + total, size - total, 0);
        if (ret > 0)
        {
            //到这里说明数据可能没有一次性的发送完毕,可能因为发送的数据量太大了
            //导致这种现象的产生,有可能是因为发送缓冲区被打满了
            //如果发送缓冲区及时的把数据发送出去,那么下一次还是会进入这里
            total += ret;
            if (total == size)
            {
                //将全部数据发送完成了
                outbuffer.clear();
                return 1;
            }
        }
        else
        {
            //IO被信号打断,概率特别低
            if (errno == EINTR)
            {
                continue;
            }
            //导致这种现象的产生,有可能是因为发送缓冲区被打满了
            //如果发送缓冲区没有及时的把数据发送出去,因为我们设置的是非阻塞sock,这个时候马上就会进行返回
            //等到发送缓冲区的空间变多了,epoll会进行通知,这个时候,又可以进行数据的发送了
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                outbuffer.erase(0, total);
                return 0;
            }

            //发送出错了
            return -1;
        }
    }
}
